package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.system.TriggerMetaCallbackDto;
import com.authine.cloudpivot.ext.dto.system.TriggerMetaDto;
import com.authine.cloudpivot.ext.enums.system.TriggerMetaStatusEnum;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.BoUtils;
import com.authine.cloudpivot.ext.utils.HttpClients;
import com.authine.cloudpivot.ext.utils.system.BeanUtils;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.common.SchemaHelper;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName ScheduledService
 * @Description: 定时任务服务
 * @Author fj
 * @Date 2021/10/22
 * @Version V1.0
 **/
@Path("ScheduledService")
@Slf4j
public class ScheduledService extends ApplicationService {
    private static final String APP_JOB = "app-job";
    private static final String ADD_JOB_URL = "/jobinfo/addJob";
    private static final String REMOVE_JOB_URL = "/jobinfo/removeJob?id=";
    private static final String action = "/application/invoke?action=";

    /**
     * 新建定时任务
     *
     * @param triggerMetaDto 定时任务
     * @return 新增结果
     */
    @Path("addJob")
    @POST
    @Operation(summary = "新建定时任务", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> addJob(@Parameter TriggerMetaDto triggerMetaDto) {
        Map<String, Object> paramMap = Maps.newHashMap();

        // 设置定时任务id，方便数据回写
        String id = SchemaHelper.getId();
        triggerMetaDto.setId(id);
        //支持自定义id
        if(!StringUtils.isEmpty(triggerMetaDto.getId())){
            triggerMetaDto.setId(triggerMetaDto.getId());
            id = triggerMetaDto.getId();
        }
        // 请求参数中增加定时任务id
        JSONObject body = Objects.isNull(triggerMetaDto.getBody()) ? new JSONObject() : JSON.parseObject(triggerMetaDto.getBody());
        body.put("triggerMetaId", id);
        paramMap.put("body", body.toJSONString());
        paramMap.put("cron", triggerMetaDto.getCron());
        paramMap.put("desc", triggerMetaDto.getDesc());
        // todo 产品暂未实现callBack功能，先传空
        paramMap.put("callBack", "");
        paramMap.put("url", HttpClients.getUrl(triggerMetaDto.getAppCode(), action.concat(triggerMetaDto.getUrl())));
        try {
            // 获取定时任务url地址
            String appJobUrl = HttpClients.getBaseUrl(APP_JOB, ADD_JOB_URL);
            String responseBody = HttpClients.execute(appJobUrl, paramMap);

            // 获取定时任务返回结果
            TriggerMetaCallbackDto triggerMetaCallbackDto = BoUtils.json2Object(responseBody, TriggerMetaCallbackDto.class);
            int code = triggerMetaCallbackDto.getCode();
            triggerMetaDto.setTask_id(String.valueOf(triggerMetaCallbackDto.getContent()));
            if (code == 200) {
                triggerMetaDto.setTrigger_status(TriggerMetaStatusEnum.UNENFORCED.id);
            } else {
                triggerMetaDto.setTrigger_status(TriggerMetaStatusEnum.FAILED.id);
                triggerMetaDto.setMsg(triggerMetaCallbackDto.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("=============创建定时器失败，失败原因：{}=============", e.getMessage());
            triggerMetaDto.setMsg(e.getMessage());
            triggerMetaDto.setTrigger_status(TriggerMetaStatusEnum.FAILED.id);
        }
        Map<String, Object> triggerMetaMap = BeanUtils.bean2Map(triggerMetaDto);
        SingleResponse<BO> createBO = BoServiceUtils.createBo(ModelConst.T_TRIGGER_META, Collections.singletonList(triggerMetaMap));
        log.info("=============创建任务触发器成功，新增数据信息：{}=============", JSONObject.toJSONString(createBO));
        return createBO;
    }

    /**
     * 修改定时任务
     *
     * @param triggerMetaDto 定时任务
     * @return 修改结果
     */
    @Path("updateJob")
    @POST
    @Operation(summary = "修改定时任务", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateJob(@Parameter TriggerMetaDto triggerMetaDto) {
        // 修改定时任务，先删除，在添加
        removeJob(triggerMetaDto);
        return addJob(triggerMetaDto);
    }

    /**
     * 删除定时任务
     *
     * @param triggerMetaDto 定时任务
     * @return 删除结果
     */
    @Path("removeJob")
    @POST
    @Operation(summary = "删除定时任务", tags = CUSTOM_SERVICE)
    public Response removeJob(@Parameter TriggerMetaDto triggerMetaDto) {
        if (!StringUtils.isEmpty(triggerMetaDto.getTask_id())) {
            String appJobUrl = HttpClients.getBaseUrl(APP_JOB, REMOVE_JOB_URL);
            String responseBody = HttpClients.execute(appJobUrl.concat(triggerMetaDto.getTask_id()), null, HttpMethod.DELETE);
            // 获取定时任务返回结果
            TriggerMetaCallbackDto triggerMetaCallbackDto = BoUtils.json2Object(responseBody, TriggerMetaCallbackDto.class);
            if (triggerMetaCallbackDto.getCode() != 200) {
                throw new BizException(triggerMetaCallbackDto.getMsg());
            }
        }
        // 删除任务触发器
        Response response = BoServiceUtils.deleteBo(ModelConst.T_TRIGGER_META, triggerMetaDto.getId(), true);
        log.info("=============删除定时任务结果：{}=============", JSONObject.toJSONString(response));
        return response;
    }
}
